package com.cljh.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.cljh.bean.Admin;
import com.cljh.bean.Path;
import com.cljh.bean.Role;
import com.cljh.bean.User;
import com.cljh.config.AuthAccess;
import com.cljh.controller.page.Code;
import com.cljh.controller.page.PageBean;
import com.cljh.controller.page.Redis;
import com.cljh.controller.page.Result;
import com.cljh.service.AdminService;
import com.cljh.service.UserService;
import com.cljh.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 用户控制类
 */
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    AdminService adminService;

    /**
     *添加
     * @param user 用户类
     * @return
     */
    @PostMapping
    public Result save(@RequestBody User user){
        String email = user.getEmail();
        if (email!=null&&!"".equals(email)){
            User user1 = userService.selectByEmailCode(email);
            Admin admin = adminService.selectByEmailCode(email);
            if (user1!=null||admin!=null){
                return new Result(Code.SAVE_ERR,null,"邮箱已经被注册过了");
            }
        }
        boolean save = userService.save(user);
        flushRedis(Code.USER_KEY);
        Integer code=save ? Code.SAVE_OK:Code.SAVE_ERR;
        String msg=save ? "添加成功":"添加失败";
        return new Result(code,save,msg);
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id){
        boolean delete = userService.delete(id);
        flushRedis(Code.USER_KEY);
        Integer code=delete ? Code.DELETE_OK:Code.DELETE_ERR;
        String msg=delete ? "删除一个成功":"删除一个失败";
        return new Result(code,delete,msg);
    }
    @PutMapping
    public Result update(@RequestBody User user){
        boolean update = userService.update(user);
        flushRedis(Code.USER_KEY);
        Integer code=update ? Code.UPDATE_OK:Code.UPDATE_ERR;
        String msg=update ? "修改成功":"修改失败";
        return new Result(code,update,msg);
    }

    @PutMapping("/money/{id}/{pay}")
    public Result updMoney(@PathVariable Integer id, @PathVariable Double pay){

        User user1 = userService.selectById(id);
        flushRedis(Code.USER_KEY);
        Double money = user1.getMoney();
        User user = new User();
        user.setId(id);
        user.setMoney(money+pay);
        boolean update = userService.update(user);
        Integer code=update ? Code.UPDATE_OK:Code.UPDATE_ERR;
        String msg=update ? "充值成功":"充值失败";
        return new Result(code,update,msg);
    }
    @PutMapping("/password/{id}/{password}")
    public Result updPassword(@PathVariable Integer id, @PathVariable String  password){
        User user = new User();
        user.setId(id);
        user.setPwd(password);
        boolean update = userService.update(user);
        flushRedis(Code.USER_KEY);
        Integer code=update ? Code.UPDATE_OK:Code.UPDATE_ERR;
        String msg=update ? "修改密码成功":"修改密码失败";
        return new Result(code,update,msg);
    }
    
    @DeleteMapping("/deleteIds")
   public Result deleteByIds(@RequestBody List<Integer> ids){
       boolean b = userService.deleteByIds(ids);
        flushRedis(Code.USER_KEY);
       Integer code=b ? Code.DELETE_OK:Code.DELETE_ERR;
       String msg=b ? "删除成功":"删除失败";
       return new Result(code,b,msg);
   }
    @GetMapping("/{id}")
    public Result selectById(@PathVariable Integer id){
        User user = userService.selectById(id);
        Integer code=user !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=user!=null ? "查询到信息":"未查询到信息";
        return new Result(code,user,msg);
    }

    /**
     * 导出excel表格
     * @param response
     * @throws Exception
     */
    @AuthAccess
    @GetMapping("/export")
    public void userList(HttpServletResponse response) throws IOException {
        //从数据库查询出所有数据
        List<User> list = userService.userList();
        //通过工具创建writer 写出到磁盘路径
//        ExcelWriter writer= ExcelUtil.getWriter(filesUploadPath+"/用户信息.xlsx");
        //内存操作，写出到浏览器
        ExcelWriter writer= ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("id" ,"id");
        writer.addHeaderAlias("username" ,"用户名");
        writer.addHeaderAlias("pwd" ,"密码");
        writer.addHeaderAlias("name" ,"姓名");
        writer.addHeaderAlias("gender" ,"性别");
        writer.addHeaderAlias("vipNumber" ,"会员账号");
        writer.addHeaderAlias("money" ,"余额");
        writer.addHeaderAlias("img" ,"头像");
        writer.addHeaderAlias("birthday" ,"生日");
        writer.addHeaderAlias("email" ,"邮箱");
        writer.addHeaderAlias("createTime" ,"创建时间");

        //一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list,true);
        //设置浏览器响应格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName= URLEncoder.encode("商品信息","UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");

        ServletOutputStream out =response.getOutputStream();
        writer.flush(out,true);
        out.close();
        writer.close();

    }

    @PostMapping("/list/{pn}/{size}")
    public Result userConditionList(@PathVariable(value = "pn") Integer pn, @PathVariable(value = "size")Integer size, @RequestBody User user){
        PageBean<User> userPageBean = userService.userConditionList(pn, size, user);
        Integer code=userPageBean !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=userPageBean!=null ? "查询到信息":"未查询到信息";
        return new Result(code,userPageBean,msg);
    }

    @GetMapping
    public Result selectList(){
        List<User> list = userService.userList1();
        Integer code=list !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=list!=null ? "查询到信息":"未查询到信息";
        return new Result(code,list,msg);
    }

    /**
     * 用户名查询
     * @param username
     * @return
     */
    @AuthAccess
    @GetMapping("check/{username}")
    public Result selectByUsername(@PathVariable String username){
        User user = userService.selectByUsername(username);
        Integer code=user !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=user!=null ? "查询到信息":"未查询到信息";
        return new Result(code,user,msg);
    }

    /**
     * 用户登录
     * @param user
     * @return
     */
    @AuthAccess
    @PostMapping("/login")
    public Result login(@RequestBody User user){
        User user1 = userService.selectByUsernameAndPwd(user);
        if (user1!=null){
                //设置token
                String s = TokenUtils.genToken(user1.getUsername(), user1.getPwd());
                System.out.println(s);
                user1.setToken(s);
        }
        Integer code = user1 != null ? Code.GET_OK : Code.GET_ERR;
        String msg = user1 != null ? "查到信息" : "未查到信息";
        return new Result(code,user1,msg);
    }

    /**
     * 用户注册
     * @param user
     * @param request
     * @param code
     * @return
     */
    @AuthAccess
    @PostMapping("/register/{code}")
    public Result register(@RequestBody User user, HttpServletRequest request, @PathVariable String code){

        code=code.toUpperCase(Locale.ROOT);
        System.out.println(code);

        //获取servletContext上下文对象
        String servletContext = (String) request.getServletContext().getAttribute("code");
        System.out.println("servletContext="+servletContext);
        if (!code.equals(servletContext)){
            return new Result(Code.SAVE_ERR,false,"验证码错误");
        }
        String uuid = IdUtil.fastSimpleUUID();
        System.out.println(uuid);
        user.setVipNumber(uuid);
        boolean save = userService.save(user);
        flushRedis(Code.USER_KEY);
        Integer c = save ? Code.SAVE_OK : Code.SAVE_ERR;
        String msg = save ? "注册成功" : "注册失败";
        return new Result(c, save, msg);
    }

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    //删除缓存
    public void flushRedis(String key){
        String s = stringRedisTemplate.opsForValue().get(key);
        if (s!=null&&!"".equals(s)){
            stringRedisTemplate.delete(key);
        }

    }
}
